package com.power.sifa.net.formact.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.ding.api.Di_userFeign;
import com.plf.common.exception.BusinessException;
import com.plf.common.utils.StringUtil;
import com.plf.core.base.dao.Ha_userDao;
import com.power.sifa.approve.dao.Apl_mainDao;
import com.power.sifa.approve.model.Apl_applicant;
import com.power.sifa.approve.model.Apl_main;
import com.power.sifa.approve.model.enumeration.St_apply;
import com.power.sifa.approve.model.enumeration.Tp_applysource;
import com.power.sifa.approve.service.Apl_archiveService;
import com.power.sifa.approve.service.Apl_dossierService;
import com.power.sifa.approve.service.Apl_mainService;
import com.power.sifa.approve.service.Apl_targetService;
import com.power.sifa.approve.thread.ThreadPoolUtil;
import com.power.sifa.net.formact.QueryFormDataUtil;
import com.power.sifa.net.formact.service.FormNextService;
import com.power.sifa.net.model.enumeration.Tp_matter;
import com.power.sifa.std.dao.Std_admunitDao;
import com.power.sifa.std.model.Std_admunit;
import com.power.sifa.std.service.Std_admuserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
@Transactional(rollbackFor = Exception.class)
public class FormNextSuperviseImpl implements FormNextService {

    @Resource
    private Std_admunitDao std_admunitDao;
    @Resource
    private Apl_targetService apl_targetService;
    @Resource
    private Apl_mainDao apl_mainDao;
    @Resource
    private Apl_mainService apl_mainService;
    @Resource
    private Ha_userDao ha_userDao;
    @Resource
    private Apl_dossierService apl_dossierService;
    @Resource
    private Apl_archiveService apl_archiveService;

    @Resource
    private Di_userFeign di_userFeign;

    @Resource
    private Std_admuserService std_admuserService;

    @Override
    public void before(String applyid, Map<String, Object> formData) throws BusinessException {
        // 校验案件号是否唯一
        Map<String, Object> masterObj = QueryFormDataUtil.getMasterData(formData);
        List<Map<String, Object>> targetObjList = QueryFormDataUtil.getSlaveData("apl_target", formData);
        String acceptcode = (String) masterObj.get("acceptcode");
        if(!StringUtil.isEmpty(acceptcode)) {
            if(acceptcode.indexOf("xxx") > -1) {
                throw new BusinessException("请修改默认的案件号");
            }
            Integer total = this.apl_mainDao.countAcceptcode(applyid, acceptcode, Tp_matter.PUB_SUPERVISE);
            if(null != total) {
                log.error("案件号{}重复 -> applyid: {}", acceptcode, applyid);
                throw new BusinessException("案件号" + acceptcode + "重复");
            }
        }

        // 保存默认改为未提交
        masterObj.put("statusapply", St_apply.WRITTEN);
        Apl_main mainObj = this.apl_mainService.getById(applyid);
        Map<String, Object> extendObj = QueryFormDataUtil.getExtendData("apl_supervise", formData);
        // 有录入人就是案件登记 (一窗来源)
        if(null == mainObj || StringUtil.isEmpty(mainObj.getSource())) {
            masterObj.put("source", Tp_applysource.CASEREG);
        }
        // 3. 查询申请人拼接赋值到主表
        {
            List<Apl_applicant> applicantList = JSON.parseArray(JSON.toJSONString(QueryFormDataUtil.getSlaveData("apl_applicant", formData)), Apl_applicant.class);
            if (!CollectionUtils.isEmpty(applicantList)) {
                List<String> nameList = applicantList.stream().map(Apl_applicant::getName).collect(Collectors.toList());
                String users = StringUtils.join(nameList, "，");
                masterObj.put("applyname", users);
                extendObj.put("applyname", users);
            } else {
                throw new RuntimeException("请补充申请人信息");
            }
        }
        // 1. 审批进行录入的申请, 有录入人id, 查询给对应的主表字段赋值
        String reguserid = (String) masterObj.get("reguserid");
        if (null != reguserid) {
            List<Map> userList = this.ha_userDao.findUserDeptsByUserid(reguserid);
            if (CollectionUtils.isEmpty(userList)) {
                log.error("根据录入人id查询信息失败");
                throw new RuntimeException("根据录入人id查询信息失败");
            }
            Map userObj = userList.get(0);
            // 有录入人就是案件登记 (一窗来源)
            if(null == mainObj || StringUtil.isEmpty(mainObj.getSource())) {
                masterObj.put("source", Tp_applysource.CASEREG);
            }
            masterObj.put("regusername", userObj.get("fullname"));
            masterObj.put("regsectionid", userObj.get("sectionid"));
            masterObj.put("regsectionname", userObj.get("sectionname"));
        }

        // 5.查询被申请人数据 TOFIX: 被申请人信息暂时隐藏
//        if (!CollectionUtils.isEmpty(targetObjList)) {
//            // 判断被申请人的联系号码是否都是在赣政通内部数据
//            List<String> phoneList = targetObjList.stream().map(el -> el.get("phone").toString()).filter(StringUtils::isNotEmpty).collect(Collectors.toList());
//            if (CollectionUtils.isEmpty(phoneList)) {
//                throw new BusinessException("请填写被申请人的联系号码");
//            }
//            ResponseDTO res  = di_userFeign.getUserByPhones(phoneList);
//            if (res.getCode() == 0) {
//                List<Di_userDto> diUserList = JSON.parseArray(JSON.toJSONString(res.getData()), Di_userDto.class);
//                if (CollectionUtils.isEmpty(diUserList)) {
//                    throw new BusinessException("被申请人联系号码错误，不属于赣政通用户");
//                } else {
//                    AtomicBoolean allUser = new AtomicBoolean(true);
//                    phoneList.stream().forEach(phone -> {
//                        if (!diUserList.stream().anyMatch(el -> el.getMobile().equals(phone))) {
//                            allUser.set(false);
//                        }
//                    });
//                    if (!allUser.get()) {
//                        throw new BusinessException("被申请人联系号码错误，不属于赣政通用户");
//                    }
//                    // 保存对应的人员信息
//                    List<Apl_target> transTargetList = BeanUtil.copyToList(targetObjList, Apl_target.class);
//                    this.std_admuserService.saveTargetDiusers(transTargetList, diUserList);
//                }
//            } else {
//                throw new BusinessException("被申请人校验错误");
//            }
//
//        } else {
//            throw new BusinessException("请填写被申请人信息");
//        }

        // 6. 设置行政区划
        this.setAdid(applyid, extendObj);
        // 7. 动态生成申请材料
//        this.GenerateMaterials(applyid, formData);
    }

    /**
     * 设置行政区划
     * @param applyid
     * @param extendObj
     */
    private void setAdid(String applyid, Map<String, Object> extendObj) {
        if (StringUtil.isEmpty((String) extendObj.get("targetadid"))) {
            log.error("请选择被申请人");
            throw new RuntimeException("请选择被申请人");
        }
        String[] ids = ((String) extendObj.get("targetadid")).split(",");
        List<String> idlist = Arrays.asList(ids);
        List<Std_admunit> admunitList = this.std_admunitDao.findByIds(idlist);
        // 5.1 如果有不同的行政区划, 默认选南昌
        if(idlist.size() > 1) {
            extendObj.put("mgradid", "360100");
        } else {
            if (CollectionUtil.isNotEmpty(admunitList)) {
                extendObj.put("mgradid", admunitList.get(0).getAdid());
            }
        }
        for (Std_admunit v : admunitList) {
            // 校验是不是南昌市的行政区划
            if(!"3601".equals(v.getAdid().substring(0, 4))) {
                log.error("请选择南昌市的被申请人行政区划");
                throw new RuntimeException("请选择南昌市的被申请人行政区划");
            }
        }
        List<String> adidnameList = new ArrayList<>(admunitList.size());
        Map<String, Std_admunit> admunitMap = new HashMap<>(16);
        for (Std_admunit std_admunit : admunitList) {
            admunitMap.put(std_admunit.getAdid(), std_admunit);
            adidnameList.add(std_admunit.getName());
        }
        extendObj.put("targetname", StringUtils.join(adidnameList, "，"));

        // 5.2 插入记录到被申请人表 (先删除再保存 - 申请表已填)
        this.apl_targetService.removeByApplyid(applyid);
//        this.apl_targetService.saveAll(targetList);
    }

    @Override
    public void after(String applyid, Map<String, Object> formData) {

    }

    @Override
    public void submit(String applyid, Apl_main mainObj) throws BusinessException {
        ThreadPoolUtil.executor.execute(() -> {
            // 6.1 初始化归档首页数据
            this.apl_archiveService.initialSuperviseArchiveData(applyid);
            // 6.2 初始化归档电子卷宗数据
            this.apl_dossierService.buildInitSuperviseDossier(applyid);
        });
    }

    @Override
    public void save(String applyid, Map<String, Object> formData) throws BusinessException {
        // 校验案件号是否唯一
        Map<String, Object> masterObj = QueryFormDataUtil.getMasterData(formData);
        String acceptcode = (String) masterObj.get("acceptcode");
        if(!StringUtil.isEmpty(acceptcode)) {
            if(acceptcode.indexOf("xxx") > -1) {
                throw new BusinessException("请修改默认的案件号");
            }
            Integer total = this.apl_mainDao.countAcceptcode(applyid, acceptcode, Tp_matter.PUB_SUPERVISE);
            if(null != total) {
                log.error("案件号{}重复 -> applyid: {}", acceptcode, applyid);
                throw new BusinessException("案件号" + acceptcode + "重复");
            }
        }

        // 保存默认改为已提交
        masterObj.put("statusapply", St_apply.COMMIT);
        // 有录入人就是案件登记 (一窗来源)
        Apl_main mainObj = this.apl_mainService.getById(applyid);
        Map<String, Object> extendObj = QueryFormDataUtil.getExtendData("apl_supervise", formData);
        if(null == mainObj || StringUtil.isEmpty(mainObj.getSource())) {
            masterObj.put("source", Tp_applysource.CASEREG);
        }
        // 3. 查询申请人拼接赋值到主表
        {
            List<Apl_applicant> applicantList = JSON.parseArray(JSON.toJSONString(QueryFormDataUtil.getSlaveData("apl_applicant", formData)), Apl_applicant.class);
            if (!CollectionUtils.isEmpty(applicantList)) {
                List<String> nameList = applicantList.stream().map(Apl_applicant::getName).collect(Collectors.toList());
                String users = StringUtils.join(nameList, "，");
                masterObj.put("applyname", users);
                extendObj.put("applyname", users);
            } else {
                throw new RuntimeException("请补充申请人信息");
            }
        }

        // 1. 审批进行录入的申请, 有录入人id, 查询给对应的主表字段赋值
        String reguserid = (String) masterObj.get("reguserid");
        if (null != reguserid) {
            List<Map> userList = this.ha_userDao.findUserDeptsByUserid(reguserid);
            if (CollectionUtils.isEmpty(userList)) {
                log.error("根据录入人id查询信息失败");
                throw new RuntimeException("根据录入人id查询信息失败");
            }
            Map userObj = userList.get(0);
            // 有录入人就是案件登记 (一窗来源)
            if(null == mainObj || StringUtil.isEmpty(mainObj.getSource())) {
                masterObj.put("source", Tp_applysource.CASEREG);
            }
            masterObj.put("regusername", userObj.get("fullname"));
            masterObj.put("regsectionid", userObj.get("sectionid"));
            masterObj.put("regsectionname", userObj.get("sectionname"));
        }
    }
}
